package com.apache.gateway.route;

import com.alibaba.fastjson.JSON;
import com.apache.gateway.config.JedisUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.cloud.gateway.support.NotFoundException;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.ArrayList;
import java.util.List;

/**
 * 核心类 getRouteDefinitions() 通过该方法获取到全部路由，每次有request过来请求的时候，都会往该方法过。
 * @description: 将定义好的路由表信息通过此类读写到redis中
 * @author: Hou Dayu
 * @date: Created in 2020/2/24
 */
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {

    public static final String  GATEWAY_ROUTES = "gateway:routes";

    @Autowired
    private JedisUtil jedisUtil;

    @Override
    public Flux<RouteDefinition> getRouteDefinitions() {
        List<RouteDefinition> routeDefinitions = new ArrayList<>();
        jedisUtil.getObjCache(GATEWAY_ROUTES,10).forEach((k,v) -> {
            routeDefinitions.add(JSON.parseObject(v.toString(), RouteDefinition.class));
        });
        return Flux.fromIterable(routeDefinitions);
    }

    @Override
    public Mono<Void> save(Mono<RouteDefinition> route) {
        return route.flatMap(routeDefinition -> {
            jedisUtil.createObjCache(GATEWAY_ROUTES, routeDefinition.getId(),
                            JSON.toJSONString(routeDefinition),0, 10);
                    return Mono.empty();
                });
    }

    @Override
    public Mono<Void> delete(Mono<String> routeId) {
        return routeId.flatMap(id -> {
            if (jedisUtil.getObjCache(GATEWAY_ROUTES,10).containsKey(id)) {
                jedisUtil.delObjCache(GATEWAY_ROUTES, id,10);
                return Mono.empty();
            }
            return Mono.defer(() -> Mono.error(new NotFoundException("路由文件没有找到: " + routeId)));
        });
    }

}
